<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>练习</title>
</head>

<body>
    <script>
        // 练习1
        function Fn1() { }
        // 添加属性n为1
        Fn1.prototype.n = 1
        // 创建Fn1实例对象fn1；此时fn1的隐式原型指向的是Fn1的显式原型
        let fn1 = new Fn1()
        // 改变Fn1的显式原型指向一个新的对象{ n: 2, m:3 };注意此时fn1的隐式原型的指向并没有改变
        Fn1.prototype = {
            n: 2,
            m: 3
        }
        // 创建新的Fn1实例对象，这个时候的Fn1的显式原型指向的是{ n: 2, m: 3 }这个对象。所以fn2的隐式原型也指向这个对象
        let fn2 = new Fn1()
        // 1, undefined, 2, 3
        console.log(fn1.n, fn1.m, fn2.n, fn2.m)


        // 练习2
        function Fn2() {}
        Object.prototype.a = function() {
            console.log('a()')
        }
        Function.prototype.b = function() {
            console.log('b()')
        }
        let fn3 = new Fn2()
        // a()
        fn3.a()
        // 此处报错，fn3的原型指向的是Object的显式原型，再往下找是按照Object的隐式原型链的方向，然而Object的隐式原型链是null3.b()
        console.log(fn3.__proto__)
        console.log(Fn2)
        // a()；这里就是将Fn2看成是对象了，任何对象的隐式原型链都会指向Object的显式原型
        Fn2.a()
        // b()
        Fn2.b()
    </script>
</body>

</html>